package token

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/logs"
	"math/rand"
	"smart_home/api/utils"
	"time"
	"tools"
)

var (
	token_key = "auth:token:%s"
	uid_key   = "auth:uid:%s"
	expire_in = 24 * 30 * time.Hour
)

type Token struct {
	Uid   string `json:"uid"`
	RegId string `json:"reg_id"`
	DevId string `json:"dev_id"`
}

// 写入token
// @param uid 用户id
// @param reg_id 极光id
// @param dev_id 登陆设备id
func Put(uid, reg_id, dev_id string) (string, error) {
	key := fmt.Sprintf("%s%d", tools.GUUID(), rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(10000000))
	tk := fmt.Sprintf(token_key, key)

	token, err := json.Marshal(&Token{
		Uid: uid,
		RegId:reg_id,
		DevId:dev_id,
	})
	if err != nil {
		logs.Error("set token error:", err)
		return "", err
	}

	if err := utils.Cache.Put(tk, string(token), expire_in); err != nil {
		logs.Error("set token error:", err)
		return "", err
	}

	uk := fmt.Sprintf(uid_key, uid)
	if err := utils.Cache.Put(uk, key, expire_in); err != nil {
		logs.Error("set token error:", err)
		return "", err
	}
	return key, nil
}

// 获取用户id
func Get(token string) *Token {
	tk := fmt.Sprintf(token_key, token)
	data := utils.Cache.Get(tk)
	if data == nil {
		return nil
	}
	td := &Token{}
	err := json.Unmarshal([]byte(fmt.Sprintf("%s", data)), td)
	if err != nil {
		logs.Error("get token error:", err)
		return nil
	}

	return td
}

// 用户是否登陆
func IsLogin(uid string) string {
	uk := fmt.Sprintf(uid_key, uid)
	token := utils.Cache.Get(uk)
	if token == nil {
		return ""
	}
	tk := fmt.Sprintf(token_key, token)
	if utils.Cache.Get(tk) == nil {
		return ""
	}
	return fmt.Sprintf("%s", token)
}

// 删除token
func Del(uid, token string) error {
	tk := fmt.Sprintf(token_key, token)
	if err := utils.Cache.Delete(tk); err != nil {
		logs.Error("delete token error:", err)
		return err
	}

	uk := fmt.Sprintf(uid_key, uid)
	if err := utils.Cache.Delete(uk); err != nil {
		logs.Error("delete token error:", err)
		return err
	}

	return nil
}
